/******************************************************************************
 cnome: A C++ source "genes" discover. :-)

 See more details at:

   http://www.codeplex.com/cnome

 The original author site is at: http://www.alemosbarbosa.com/

 Copyright (c) 2008-2010 Alexandre Lemos Barbosa.
 Distributed under the MIT License. (See accompanying file LICENSE-MIT.txt 
 or at http://www.codeplex.com/cnome/license)
 ******************************************************************************/

#include "cnome_config.h"

#include <fstream>
#include <iostream>
#include <stdio.h>

#include "auxiliar.h"
#include "iterator.h"
#include "typedefs.h"
#include "symbol.h"

using namespace std;
using namespace boost::wave;

namespace cnome {
const char* cfgFile="cnome.cfg";

// TODO (alb): Remove the commented lines below after certify the new PrintSymbols method is working properly and
//             the old method isn't necessary anymore as a reference.
// 21dec2010
//
//const char* my_itoa(int a, char* buf=0) {  // It is not thread safe
//    
//    static char buffer[20];
//    if (!buf)
//        buf = buffer;
//
//    sprintf(buf,"%d",a);
//    //return itoa(a,buffer,10);
//    return buf;
//}
//
//std::string adns2Str(const adornersT& adns) {
//    std::string ret;
//    for (adornersT::const_iterator it = adns.begin(); it!=adns.end(); it++)
//        ret += *it==T_CONST?string(" ")+it->get_value().c_str():it->get_value().c_str();
//
//    return ret;
//}
//
//void PrintSymbols() {
//    char strLinNum[20];
//    char strColNum[20];
//    
//    for (itSymbolItem it = cnome_symbols.begin(); it != cnome_symbols.end(); it++) {
//            if ( it->second->get_symbol_type() != symbol::internal &&
//                 (	    it->second->get_symbol_type() != symbol::keyword 
//                    ||  it->second->get_symbol_status() != symbol::declared )
//                ) {
//                cerr << it->first << ": " << ( (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_CLASS_NAME?"CLASS_NAME":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_ENUM_NAME?"ENUM_NAME":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_ORIGINAL_NAMESPACE_NAME?"ORIGINAL_NAMESPACE_NAME":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_TEMPLATE_NAME?"TEMPLATE_NAME":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_NAMESPACE_ALIAS?"NAMESPACE_ALIAS":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_TYPEDEF_NAME?"TYPEDEF_NAME":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_TEMPLATE_PARAMETER?"TEMPLATE_PARAMETER":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_TEMPLATE_VARIABLE?"TEMPLATE_VARIABLE":
//                                               (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::NONE
//                                                   ? (    (!it->second->get_type_symbol()
//                                                        ? ""
//                                                        : (   it->second->get_type_symbol()->to_str()
//                                                            + adns2Str(it->second->get_type_symbol()->get_adorners())
//                                                            + adns2Str(it->second->get_adorners())
//                                                          ).c_str() )
//                                                       + std::string(": IDENTIFIER")).c_str():
//                                               it->second->get_symbol_type()==symbol::keyword?"KEYWORD":
//                                               (*it->second)==T_ELLIPSIS ? "VAR_PARAMETER" :
//                                               "UNKNOWN"
//                                             )
//                      << ": " << ( (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::NONE ? symbol::strSymbolType[it->second->get_symbol_type()] : "" )
//                      << ": " << (   (*it->second)==T_IDENTIFIER && it->second->get_identifier_type() == symbol::T_TYPEDEF_NAME 
//                              ? (   it->second->get_type_symbol()
//                                  ? (   it->second->get_type_symbol()->to_str() 
//                                      + adns2Str(it->second->get_type_symbol()->get_adorners())
//                                      + adns2Str(it->second->get_adorners())
//                                    ).c_str()
//                                  :  "") 
//                              : "" )
//                      << (it->second->get_symbol_type()==symbol::keyword?"":
//                            ( std::string(": (") + (*it->second).get_position().get_file().c_str() + ":"
//                              + my_itoa((*it->second).get_position().get_line(),strLinNum) + "," 
//                              + my_itoa((*it->second).get_position().get_column(),strColNum)
//                              + ")" ).c_str())
//                      << endl;
//
//            if (it->second->get_references().size() > 0) {
//                cerr << "     Referenced at: " << endl;
//                for (std::map<iterator, symbolPtr>::iterator itr = it->second->get_references().begin(); itr != it->second->get_references().end(); itr++) {
//                    cerr << "     " << (itr->second?itr->second->to_str():"") << endl;
//                }
//            }
//        }
//    }
//}

void PrintSymbols() {
    for (itSymbolItem it = cnome_symbols.begin(); it != cnome_symbols.end(); it++) {
            if ( it->second->get_symbol_type() != symbol::internal &&
                 (	    it->second->get_symbol_type() != symbol::keyword 
                    ||  it->second->get_symbol_status() != symbol::declared )
                ) {
                cerr << *it->second;
        }
    }
}


void readConfig(context_t& ctx) {
    ifstream file(cfgFile);

    if (!file)
        return;
    
    while(!file.eof())
    {
        char ch;
        file.get(ch);
        string cmd;
        getline(file, cmd);
        switch(ch) {
            case 'D':
                ctx.add_macro_definition(cmd, true);
                break;
            case 'I':
                ctx.add_include_path(cmd.c_str());
                break;
            case 'S':
                ctx.add_sysinclude_path(cmd.c_str());
                break;
        }
    }
}
}  // namespace cnome

